package com.jetinno.simple

import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.IdRes
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.lifecycleScope
import com.jetinno.simple.utils.InputMethodUtil
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import org.greenrobot.eventbus.EventBus
import timber.log.Timber

/**
 * Created by zhangyuncai on 2021/7/14.
 */
abstract class SimpleFragment : Fragment(), View.OnClickListener {

    val TAG = this::class.java.simpleName

    //使用懒加载方式得到mContext和mActivity,但不能在onAttach使用这两个字段
    val mContext: Context by lazy { requireContext() }
    val mActivity: FragmentActivity by lazy { requireActivity() }
    lateinit var rootView: View

    var isViewPrepared = false // 标识fragment视图已经初始化完毕

    var hasFetchData = false // 标识已经触发过懒加载数据

    var isRegisterEventBus = false

    protected open fun useDatabing(inflater: LayoutInflater, container: ViewGroup?): View? {
        return null
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        logLify("onCreateView")
        if (!::rootView.isInitialized) {
            val bindingView = useDatabing(inflater, container)
            if (bindingView == null) {
                rootView = inflater.inflate(getLayoutId(), container, false)
            } else {
                rootView = bindingView
            }
        }
        val parent = rootView.parent as? ViewGroup
        parent?.removeView(rootView)
        return rootView
    }

    protected abstract fun getLayoutId(): Int

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        findViewByIds()
        if (isRegisterEventBus && !EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this)
        }
        initView()
        initEvent()
        rootView.setOnClickListener {
            // 防止事件击穿
        }
    }

    open fun findViewByIds() {}

    protected fun <T : View> findViewById(@IdRes id: Int): T {
        return rootView.findViewById(id)
    }

    protected fun fileFragment(containerId: Int, fragment: Fragment?) {
        fragment?.let {
            childFragmentManager
                .beginTransaction()
                .replace(containerId, it)
                .commitAllowingStateLoss()
        }
    }

    protected open fun removeFragment(fragmentManager: FragmentManager, fragment: Fragment?) {
        fragment?.let {
            fragmentManager
                .beginTransaction()
                .remove(it)
                .commitAllowingStateLoss()
        }
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        isViewPrepared = true
        lazyFetchDataIfPrepared()
    }

    protected fun runOnUiThread(runnable: Runnable) {
        activity?.runOnUiThread(runnable)
    }

    /**
     * 延时一段时间收到消息
     * @param time 延时时间,毫秒
     * @param callback 延时时间已到回调
     */
    protected fun delayTime(time: Long, callback: ((Boolean) -> Unit)): Job {
        return lifecycleScope.launch {
            try {
                delay(time)
                callback.invoke(true)
            } catch (throwable: Throwable) {
                throwable.printStackTrace()
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        hasFetchData = false
        isViewPrepared = false
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this)
        }
        InputMethodUtil.closeKeyBoard(mActivity)
        logLify("onDestroyView")
    }

    // 懒加载相关 *********************************************************************************************************
    override fun setUserVisibleHint(isVisibleToUser: Boolean) {
        super.setUserVisibleHint(isVisibleToUser)
        logLify("setUserVisibleHint:$isVisibleToUser")
        if (isVisibleToUser) {
            lazyFetchDataIfPrepared()
        }
    }

    protected fun lazyFetchDataIfPrepared() {
        // 用户可见fragment && 没有加载过数据 && 视图已经准备完毕
        if (userVisibleHint && !hasFetchData && isViewPrepared) {
            hasFetchData = true
            lazyFetchData()
        }
    }

    /**
     * 懒加载的方式获取数据，仅在满足fragment可见和视图已经准备好的时候调用一次
     */
    protected abstract fun lazyFetchData()

    protected abstract fun initView()

    protected abstract fun initEvent()

    protected fun addOnClick(vararg ids: Int) {
        for (id in ids) {
            findViewById<View>(id).setOnClickListener { v -> onClick(v) }
        }
    }

    override fun onClick(v: View) {}

    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        logLify("onHiddenChanged:$hidden")
    }

    protected fun viewIsNull(): Boolean {
        return rootView == null
    }

    protected fun closeKeyBoard() {
        InputMethodUtil.closeKeyBoard(mActivity)
    }

    /**
     * 打印生命周期
     */
    private fun logLify(state: String) {
        Timber.i(TAG, state)
    }
}